﻿/*------------------------------------------------------------------------

PROJECTIONMAKER.HPP v1.0.1

Copyright 楊志賢 CxxlMan, 2012 - 2013
All Rights Reserved

------------------------------------------------------------------------*/

#if !defined(__PROJECTIONMAKER_HPP_Cxxl3D)
#define __PROJECTIONMAKER_HPP_Cxxl3D

#include <Sys\MATH.HPP>

#include "MATRIX.HPP"
#include "CAMERA.HPP"


namespace Cxxl3D
{

// OpenGL native right hand system
// fovy = 垂直方向的視角`
// aspect = 水平方向視角對重直方向視角的比值
// z_hear = 鏡頭可以看到的最近距離
// z_far = 鏡頭可以看到的最遠距離
inline CxxlMan::CSmart_Ptr<Matrix4x4> MatrixPerspectiveRH_OpenGL(float fovy, float aspect,
										float z_near, float z_far)
{
  Matrix4x4 *pMatrix4x4 = new Matrix4x4;
	pMatrix4x4->Identity();

	float fovy_radian = DegreeToRadian(fovy);
	float yscale = Cot(fovy_radian/2.0f);
	float xscale = yscale * aspect;

	(*pMatrix4x4)[0][0] = xscale;
	(*pMatrix4x4)[1][1] = yscale;
	(*pMatrix4x4)[2][2] = (z_far + z_near)/(z_near - z_far);
	(*pMatrix4x4)[2][3] = -1.0f;
	(*pMatrix4x4)[3][2] = 2.0f * z_far * z_near / (z_near - z_far);
	(*pMatrix4x4)[3][3] = 0.0f;

	return pMatrix4x4;
}


// DirectX right hand system
// fovy = 垂直方向的視角
// aspect = 水平方向視角對重直方向視角的比值
// z_hear = 鏡頭可以看到的最近距離
// z_far = 鏡頭可以看到的最遠距離
inline CxxlMan::CSmart_Ptr<Matrix4x4> MatrixPerspectiveRH_DirectX(float fovy, float aspect,
										 float z_near, float z_far)
{
  Matrix4x4 *pMatrix4x4 = new Matrix4x4;
	pMatrix4x4->Identity();

	float fovy_radian = DegreeToRadian(fovy);
	float yscale = Cot(fovy_radian/2.0f);
	float xscale = yscale * aspect;

	(*pMatrix4x4)[0][0] = xscale;
	(*pMatrix4x4)[1][1] = yscale;
	(*pMatrix4x4)[2][2] = z_far / (z_near - z_far);
	(*pMatrix4x4)[2][3] = -1.0f;
	(*pMatrix4x4)[3][2] = (z_near * z_far) /(z_near - z_far);
	(*pMatrix4x4)[3][3] = 0.0f;

	return pMatrix4x4;
}


// OpenGL native right hand system
// w = 鏡頭水平方向可以看到的範圍
// h = 鏡頭垂直方向可以看到的範圍
// z_hear = 鏡頭可以看到的最近距離
// z_far = 鏡頭可以看到的最遠距離
inline CxxlMan::CSmart_Ptr<Matrix4x4> MatrixOrthoRH_OpenGL(float w, float h, float z_near, float z_far)
{
  Matrix4x4 *pMatrix4x4 = new Matrix4x4;
	pMatrix4x4->Identity();

	(*pMatrix4x4)[0][0] = 2.0f/w;
	(*pMatrix4x4)[1][1] = 2.0f/h;
	(*pMatrix4x4)[2][2] = 2.0f/(z_near - z_far);
	(*pMatrix4x4)[3][2] = (z_far + z_near)/(z_near - z_far);
	(*pMatrix4x4)[3][3] = 1.0f;

	return pMatrix4x4;
}


// DirectX right hand system
// w = 鏡頭水平方向可以看到的範圍
// h = 鏡頭垂直方向可以看到的範圍
// z_hear = 鏡頭可以看到的最近距離
// z_far  = 鏡頭可以看到的最遠距離
CxxlMan::CSmart_Ptr<Matrix4x4> MatrixOrthoRH_DirectX(float w, float h, float z_near, float z_far)
{
  Matrix4x4 *pMatrix4x4 = new Matrix4x4;
	pMatrix4x4->Identity();

	(*pMatrix4x4)[0][0] = 2.0f/w;
	(*pMatrix4x4)[1][1] = 2.0f/h;
	(*pMatrix4x4)[2][2] = 1.0f/(z_near - z_far);
	(*pMatrix4x4)[3][2] = z_near / (z_near - z_far);

	return pMatrix4x4;
}



}   /* namespace Cxxl3D */
#endif
